<!DOCTYPE html>
<html>
<head>
<title>Pulley System</title>
</head>
<body>
<canvas id="physicsCanvas" width="450" height="500"></canvas>
<script>
const canvas = document.getElementById('physicsCanvas');
const ctx = canvas.getContext('2d');

// Style settings
ctx.lineWidth = 1.5;
ctx.strokeStyle = 'black';
ctx.fillStyle = 'black';
ctx.font = 'italic 22px Times New Roman';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';

// Parameters
const cx = 225;
const cy = 150;
const R = 70;
const massSize = 45;
const ropeLength = 200;
const ceilingY = 60;
const ceilingWidth = 260;
const hatchSpacing = 20;

// Helper function to draw a line with an arrow at the end
function drawArrow(ctx, fromx, fromy, tox, toy) {
    const headlen = 10; // length of head in pixels
    const dx = tox - fromx;
    const dy = toy - fromy;
    const angle = Math.atan2(dy, dx);
    // Draw the line
    ctx.beginPath();
    ctx.moveTo(fromx, fromy);
    ctx.lineTo(tox, toy);
    ctx.stroke();
    // Draw the arrow head
    ctx.beginPath();
    ctx.moveTo(tox, toy);
    ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
    ctx.moveTo(tox, toy);
    ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
    ctx.stroke();
}

// 1. Draw Ceiling
ctx.beginPath();
ctx.moveTo(cx - ceilingWidth / 2, ceilingY);
ctx.lineTo(cx + ceilingWidth / 2, ceilingY);
ctx.stroke();

// Draw hatching
const numHatches = ceilingWidth / hatchSpacing;
for (let i = 0; i <= numHatches; i++) {
    ctx.beginPath();
    ctx.moveTo(cx - ceilingWidth / 2 + i * hatchSpacing, ceilingY);
    ctx.lineTo(cx - ceilingWidth / 2 + i * hatchSpacing - 10, ceilingY - 10);
    ctx.stroke();
}

// 2. Draw Pulley Suspension
ctx.beginPath();
ctx.moveTo(cx, ceilingY);
ctx.lineTo(cx, cy);
ctx.stroke();

// 3. Draw Pulley
ctx.beginPath();
ctx.arc(cx, cy, R, 0, 2 * Math.PI);
ctx.stroke();

// 4. Draw Rope
ctx.beginPath();
// Left side
ctx.moveTo(cx - R, cy);
ctx.lineTo(cx - R, cy + ropeLength);
// Right side
ctx.moveTo(cx + R, cy);
ctx.lineTo(cx + R, cy + ropeLength);
// Arc over pulley
ctx.arc(cx, cy, R, Math.PI, 0); // from 180 deg to 0 deg
ctx.stroke();

// 5. Draw Masses
ctx.strokeRect(cx - R - massSize / 2, cy + ropeLength, massSize, massSize);
ctx.strokeRect(cx + R - massSize / 2, cy + ropeLength, massSize, massSize);

// 6. Add Labels and Annotations
// Mass labels
ctx.fillText("M", cx - R - massSize / 2 - 20, cy + ropeLength + massSize / 2);
ctx.fillText("m", cx + R + massSize / 2 + 15, cy + ropeLength + massSize / 2);

// Radius R and its lines
drawArrow(ctx, cx, cy, cx - R, cy); // Horizontal radius to the left
ctx.fillText("R", cx - R / 2 - 10, cy - 15);

const theta = Math.PI / 6; // 30 degrees
// Angle is measured up from horizontal, so use negative for canvas's y-down system
const angledRadiusX = cx + R * Math.cos(-theta);
const angledRadiusY = cy + R * Math.sin(-theta);
drawArrow(ctx, cx, cy, angledRadiusX, angledRadiusY);

// Angle theta annotation
// Dashed horizontal line
ctx.beginPath();
ctx.setLineDash([5, 3]);
ctx.moveTo(cx, cy);
ctx.lineTo(cx + R + 25, cy);
ctx.stroke();
ctx.setLineDash([]);

// Angle arc with arrow
const arcRadius = 30;
ctx.beginPath();
ctx.arc(cx, cy, arcRadius, 0, -theta, true); // from 0 to -theta (upwards)
ctx.stroke();

// Arrow on the arc (open triangle)
const arrowOnArcAngle = -theta;
const arrowOnArcX = cx + arcRadius * Math.cos(arrowOnArcAngle);
const arrowOnArcY = cy + arcRadius * Math.sin(arrowOnArcAngle);
const tangentAngle = arrowOnArcAngle + Math.PI / 2; // Direction of CCW motion
const arrowSize = 7;
ctx.beginPath();
ctx.moveTo(arrowOnArcX - arrowSize * Math.cos(tangentAngle - Math.PI / 4), arrowOnArcY - arrowSize * Math.sin(tangentAngle - Math.PI / 4));
ctx.lineTo(arrowOnArcX, arrowOnArcY); // Tip of the arrow
ctx.lineTo(arrowOnArcX - arrowSize * Math.cos(tangentAngle + Math.PI / 4), arrowOnArcY - arrowSize * Math.sin(tangentAngle + Math.PI / 4));
ctx.stroke();

// Theta label
ctx.fillText("θ", cx + arcRadius + 12, cy - 15);

// Chinese label "水平线"
ctx.font = '22px "KaiTi", "SimSun"'; // Use a font that supports Chinese characters
ctx.textAlign = 'left';
ctx.fillText("水平线", cx + R + 35, cy);

</script>
</body>
</html>